// ============================================================================
// 此文件已废弃，所有 WebSocket 功能已迁移到 Rust 实现
// 请使用 websocket_service_rust.dart 中的 WebSocketServiceRust
// ============================================================================

/*
import 'dart:async';
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'dart:typed_data';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:web_socket_channel/io.dart';
import '../config/app_config.dart';
import '../../shared/storage/storage_service.dart';

enum WebSocketStatus {
  disconnected,
  connecting,
  connected,
  error,
}

class WebSocketService {
  final StorageService _storageService;
  WebSocketChannel? _channel;
  WebSocket? _webSocket; // 保存WebSocket引用以便发送ping
  WebSocketStatus _status = WebSocketStatus.disconnected;
  StreamController<dynamic>? _messageController;
  Timer? _reconnectTimer;
  Timer? _pingTimer; // ping心跳定时器
  Timer? _pongTimeoutTimer; // pong超时定时器
  int _reconnectAttempts = 0;
  DateTime? _lastPongTime; // 最后一次收到pong的时间
  static const int maxReconnectAttempts = 5;
  static const Duration pingInterval = Duration(seconds: 30); // 每30秒发送一次ping
  static const Duration pongTimeout = Duration(seconds: 60); // 60秒内没收到pong则认为连接断开

  WebSocketService(this._storageService) {
    _messageController = StreamController<dynamic>.broadcast();
  }

  WebSocketStatus get status => _status;
  Stream<dynamic> get messageStream => _messageController!.stream;

  Future<void> connect() async {
    if (_status == WebSocketStatus.connected ||
        _status == WebSocketStatus.connecting) {
      developer.log('WebSocket already connected or connecting, skipping', name: 'WebSocketService');
      return;
    }

    _status = WebSocketStatus.connecting;
    _notifyStatusChange();
    developer.log('🔌 Connecting to WebSocket...', name: 'WebSocketService');

    try {
      final token = await _storageService.getToken();
      if (token == null) {
        developer.log('❌ No token found, cannot connect WebSocket', name: 'WebSocketService');
        _status = WebSocketStatus.error;
        _notifyStatusChange();
        return;
      }

      // 获取subscription_id（优先使用存储的，否则使用open_id或username）
      String? subscriptionId = await _storageService.getSubscriptionId();
      if (subscriptionId == null || subscriptionId.isEmpty) {
        // 如果没有subscription_id，尝试从用户信息中获取open_id
        final userInfoJson = await _storageService.getUserInfo();
        if (userInfoJson != null) {
          try {
            final userInfo = jsonDecode(userInfoJson) as Map<String, dynamic>;
            subscriptionId = userInfo['open_id']?.toString() ?? 
                            userInfo['snowflake_id']?.toString() ?? 
                            userInfo['username']?.toString();
          } catch (e) {
            developer.log('⚠️ Failed to parse user info for subscription_id: $e', name: 'WebSocketService');
          }
        }
      }

      if (subscriptionId == null || subscriptionId.isEmpty) {
        developer.log('❌ No subscription_id found, cannot connect WebSocket', name: 'WebSocketService');
        _status = WebSocketStatus.error;
        _notifyStatusChange();
        return;
      }

      // 构建正确的WebSocket URL: /ws/{subscription_id}
      final wsBaseUrl = AppConfig.wsBaseUrl;
      final uri = Uri.parse('$wsBaseUrl/$subscriptionId');
      developer.log('🔗 WebSocket URI: $uri', name: 'WebSocketService');
      developer.log('🔑 Using subscription_id: $subscriptionId', name: 'WebSocketService');
      
      // 使用HttpClient手动升级到WebSocket以支持自定义headers
      final httpClient = HttpClient();
      final request = await httpClient.getUrl(uri);
      
      // 设置Authorization header
      request.headers.set('Authorization', 'Bearer $token');
      request.headers.set('User-Agent', 'VioletIM-Flutter');
      
      final response = await request.close();
      
      // 检查响应状态
      if (response.statusCode != 101) {
        // 101是WebSocket升级状态码
        developer.log('❌ WebSocket upgrade failed: ${response.statusCode}', name: 'WebSocketService');
        await response.drain();
        httpClient.close();
        _status = WebSocketStatus.error;
        _notifyStatusChange();
        _scheduleReconnect();
        return;
      }
      
      // 升级到WebSocket
      final socket = await response.detachSocket();
      final webSocket = WebSocket.fromUpgradedSocket(
        socket,
        serverSide: false,
      );
      
      // 保存WebSocket引用以便发送ping
      _webSocket = webSocket;
      
      // 包装成WebSocketChannel
      _channel = IOWebSocketChannel(webSocket);

      // 监听channel流
      _channel!.stream.listen(
        (message) {
          _handleMessage(message);
        },
        onError: (error) {
          developer.log('❌ WebSocket error: $error', name: 'WebSocketService');
          _handleError(error);
        },
        onDone: () {
          developer.log('🔌 WebSocket connection closed', name: 'WebSocketService');
          _handleDisconnect();
        },
      );

      _status = WebSocketStatus.connected;
      _reconnectAttempts = 0;
      _lastPongTime = DateTime.now(); // 初始化pong时间
      _notifyStatusChange();
      _startPingTimer(); // 启动ping心跳
      developer.log('✅ WebSocket connected successfully', name: 'WebSocketService');
    } catch (e) {
      developer.log('❌ WebSocket connection failed: $e', name: 'WebSocketService');
      _status = WebSocketStatus.error;
      _notifyStatusChange();
      _scheduleReconnect();
    }
  }

  void disconnect() {
    developer.log('🔌 Disconnecting WebSocket...', name: 'WebSocketService');
    _stopPingTimer(); // 停止ping心跳
    _stopPongTimeoutTimer(); // 停止pong超时检测
    _reconnectTimer?.cancel();
    _channel?.sink.close();
    _channel = null;
    _webSocket = null;
    _status = WebSocketStatus.disconnected;
    _notifyStatusChange();
    developer.log('✅ WebSocket disconnected', name: 'WebSocketService');
  }

  void send(dynamic message) {
    if (_status == WebSocketStatus.connected && _channel != null) {
      try {
        String messageStr;
        if (message is String) {
          messageStr = message;
        } else if (message is Map) {
          messageStr = jsonEncode(message);
        } else {
          messageStr = message.toString();
        }
        _channel!.sink.add(messageStr);
        developer.log('📤 Sent WebSocket message: ${messageStr.length > 100 ? messageStr.substring(0, 100) + "..." : messageStr}', name: 'WebSocketService');
      } catch (e) {
        developer.log('❌ Error sending WebSocket message: $e', name: 'WebSocketService');
      }
    } else {
      developer.log('⚠️ Cannot send message: WebSocket not connected (status: $_status)', name: 'WebSocketService');
    }
  }

  void _handleMessage(dynamic message) {
    try {
      // 尝试解析JSON消息
      Map<String, dynamic>? messageMap;
      if (message is String) {
        // 检查是否是pong响应（某些服务器可能发送文本pong）
        if (message == 'pong' || message.toLowerCase() == 'pong') {
          _handlePong();
          return;
        }
        
        try {
          messageMap = jsonDecode(message) as Map<String, dynamic>;
          
          // 检查是否是pong消息（JSON格式）
          if (messageMap['type'] == 'pong') {
            _handlePong();
            return;
          }
          
          // 忽略ping消息（我们发送的）
          if (messageMap['type'] == 'ping') {
            return;
          }
          
          developer.log('📨 Received WebSocket message: ${messageMap['message_id'] ?? 'unknown'}', name: 'WebSocketService');
        } catch (e) {
          // 如果不是JSON，直接发送原始字符串
          developer.log('📨 Received WebSocket text message (non-JSON): ${message.toString().substring(0, message.toString().length > 100 ? 100 : message.toString().length)}', name: 'WebSocketService');
          _messageController?.add(message);
          return;
        }
      } else if (message is Map) {
        messageMap = message as Map<String, dynamic>;
        
        // 检查是否是pong消息
        if (messageMap['type'] == 'pong') {
          _handlePong();
          return;
        }
        
        // 忽略ping消息
        if (messageMap['type'] == 'ping') {
          return;
        }
        
        developer.log('📨 Received WebSocket message: ${messageMap['message_id'] ?? 'unknown'}', name: 'WebSocketService');
      }

      // 发送解析后的消息
      if (messageMap != null) {
        _messageController?.add(messageMap);
      } else {
        _messageController?.add(message);
      }
    } catch (e) {
      developer.log('❌ Error handling WebSocket message: $e', name: 'WebSocketService');
      // 即使解析失败，也发送原始消息
      _messageController?.add(message);
    }
  }
  
  /// 处理收到的pong消息
  void _handlePong() {
    _lastPongTime = DateTime.now();
    _stopPongTimeoutTimer(); // 重置pong超时检测
    developer.log('🏓 Received WebSocket Pong, connection is alive', name: 'WebSocketService');
  }
  
  /// 启动ping心跳定时器
  /// 注意：Dart的WebSocket没有公开的ping方法，我们使用应用层的心跳消息
  void _startPingTimer() {
    _stopPingTimer(); // 先停止旧的定时器
    
    _pingTimer = Timer.periodic(pingInterval, (timer) {
      if (_status == WebSocketStatus.connected && _channel != null) {
        try {
          // 发送应用层的ping消息（JSON格式）
          // 服务器应该回复pong消息
          final pingMessage = jsonEncode({
            'type': 'ping',
            'timestamp': DateTime.now().millisecondsSinceEpoch,
          });
          _channel!.sink.add(pingMessage);
          developer.log('🏓 Sent WebSocket Ping (application layer)', name: 'WebSocketService');
          
          // 启动pong超时检测
          _startPongTimeoutTimer();
        } catch (e) {
          developer.log('❌ Error sending ping: $e', name: 'WebSocketService');
          _handleError(e);
        }
      } else {
        // 如果连接已断开，停止ping定时器
        _stopPingTimer();
      }
    });
  }
  
  /// 停止ping心跳定时器
  void _stopPingTimer() {
    _pingTimer?.cancel();
    _pingTimer = null;
  }
  
  /// 启动pong超时检测定时器
  void _startPongTimeoutTimer() {
    _stopPongTimeoutTimer(); // 先停止旧的定时器
    
    _pongTimeoutTimer = Timer(pongTimeout, () {
      // 检查是否在超时时间内收到pong
      if (_lastPongTime == null) {
        developer.log('⚠️ No pong received, connection may be dead', name: 'WebSocketService');
        _handleError('Pong timeout');
        return;
      }
      
      final timeSinceLastPong = DateTime.now().difference(_lastPongTime!);
      if (timeSinceLastPong > pongTimeout) {
        developer.log('⚠️ Pong timeout (${timeSinceLastPong.inSeconds}s), connection may be dead', name: 'WebSocketService');
        _handleError('Pong timeout');
      }
    });
  }
  
  /// 停止pong超时检测定时器
  void _stopPongTimeoutTimer() {
    _pongTimeoutTimer?.cancel();
    _pongTimeoutTimer = null;
  }

  void _handleError(dynamic error) {
    _status = WebSocketStatus.error;
    _notifyStatusChange();
    _scheduleReconnect();
  }

  void _handleDisconnect() {
    _status = WebSocketStatus.disconnected;
    _notifyStatusChange();
    _scheduleReconnect();
  }

  void _scheduleReconnect() {
    if (_reconnectAttempts >= maxReconnectAttempts) {
      return;
    }

    _reconnectTimer?.cancel();
    _reconnectAttempts++;
    final delay = Duration(seconds: _reconnectAttempts * 2);

    _reconnectTimer = Timer(delay, () {
      if (_status != WebSocketStatus.connected) {
        connect();
      }
    });
  }

  void _notifyStatusChange() {
    _messageController?.add({
      'type': 'status',
      'status': _status.toString(),
    });
  }

  void dispose() {
    disconnect();
    _messageController?.close();
    _reconnectTimer?.cancel();
    _stopPingTimer();
    _stopPongTimeoutTimer();
  }
}
*/

